Skip to content

Conversation

@ammar-agent
Copy link
Collaborator

@ammar-agent ammar-agent commented Dec 9, 2025

Problem

The previous shimmer implementation using Web Worker + OffscreenCanvas still showed 16% CPU usage on the main thread. Even though the animation loop ran in a worker, canvas compositing still hits the main thread.

Solution

Replace with pure CSS using background-clip: text:

  • Gradient background clipped to text shape
  • Dark band (75% darker via color-mix) sweeps across
  • Animated via background-position - no JS involved
  • Works with any base color including white

Why this is better

  • No JS animation loop - browser handles it natively
  • No canvas rendering - just CSS
  • No worker overhead - no message passing, no Comlink
  • ~50 lines vs ~230 lines before

Trade-off

background-position isn't compositor-only so it does trigger repaints, but for small text elements like "Thinking..." this is negligible compared to the canvas/worker overhead.

Files changed

  • src/browser/components/ai-elements/shimmer.tsx - Pure CSS implementation
  • src/browser/styles/globals.css - Added .shimmer-text class and keyframe
  • Deleted src/browser/workers/shimmerWorker.ts - No longer needed

Generated with mux

@chatgpt-codex-connector
Copy link

Codex usage limits have been reached for code reviews. Please check with the admins of this repo to increase the limits by adding credits.
Repo admins can enable using credits for code reviews in their settings.

@ammar-agent ammar-agent force-pushed the fix-shimmer-frame-drops-thinking branch 5 times, most recently from fa69834 to edb1a0d Compare December 9, 2025 01:32
@ammar-agent ammar-agent changed the title 🤖 perf: rewrite shimmer with pure CSS transforms (zero CPU) 🤖 perf: rewrite shimmer with pure CSS (no JS animation) Dec 9, 2025
@ammar-agent ammar-agent force-pushed the fix-shimmer-frame-drops-thinking branch from edb1a0d to 98853d2 Compare December 9, 2025 01:36
Replace canvas + Web Worker approach with pure CSS:
- Base text layer (muted color) provides layout
- Highlight text layer slides via transform: translateX
- Gradient mask reveals highlight band as it passes

Transform animations run entirely on the compositor thread (GPU).
Zero main thread involvement, zero JS, zero requestAnimationFrame.

Previous approaches all had main thread overhead:
- motion/react: backgroundPosition triggers repaints
- Web Worker + OffscreenCanvas: compositing still hits main thread
- CSS background-position: also triggers repaints

Only transform/opacity/filter are truly compositor-only.
@ammar-agent ammar-agent force-pushed the fix-shimmer-frame-drops-thinking branch from 98853d2 to 228de26 Compare December 9, 2025 01:44
@ammario ammario merged commit d2f335a into main Dec 9, 2025
19 checks passed
@ammario ammario deleted the fix-shimmer-frame-drops-thinking branch December 9, 2025 01:50
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants